import datetime
import random
import re

from flask import current_app, jsonify, session
from flask import make_response
from flask import request


from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blu


# 注销退出操作

@passport_blu.route('/logout')
def logout():
    session.pop("user_id",None)
    session.pop("nick_name",None)
    session.pop("mobile",None)
    # 要清楚is_admin的值，如果不清除，先登录管理员，会保存到session，再登录普通用户，又能访问管理员页面
    session.pop("is_admin",None)
    print("退出操作执行中")

    return jsonify(errno = RET.OK, errmsg = "退出成功")



"""
登录逻辑
    1. 获取参数和判断是否有值
    2. 从数据库查询出指定的用户
    3. 校验密码
    4. 保存用户登录状态
    5. 返回结果
"""

@passport_blu.route('/login',methods =['POST'])
def login():
    parameter_num = request.json
    mobile = parameter_num.get("mobile")
    password = parameter_num.get("password")
    print(1111111111111111)

    print("登录" + password)

    if not all([mobile,password]):
        return jsonify(errno = RET.PARAMERR, errmsg = "参数不够")

    # 向数据库查找用户名
    try:
        user = User.query.filter_by(mobile = mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR,errmsg = "数据未能查到")

    if not user:
        return jsonify(errno = RET.NODATA, errmsg = "没有该用户")



    # try:
    #     pwd = User.query.filter_by(password = password)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     return jsonify(errno = RET.DBERR ,errmsg = "数据找不到")
    #
    # if str(pwd) != str(password) :
    #     return jsonify(errno = RET.NODATA, errmsg = "密码错误")
    #



        # 3. 校验密码
    if not user.check_password(password):
        return jsonify(errno=RET.PWDERR, errmsg="密码错误")

    # 记录用户登录状态
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile

    user.last_login = datetime.datetime.now()


    print(user.last_login)

    return jsonify(errno = RET.OK,errmsg = "登录成功")





"""
    注册的逻辑
    1. 获取参数
    2. 校验参数
    3. 取到服务器保存的真实的短信验证码内容
    4. 校验用户输入的短信验证码内容和真实验证码内容是否一致
    5. 如果一致，初始化 User 模型，并且赋值属性
    6. 将 user 模型添加数据库
    7. 返回响应
    :return:
    """

#  TODO 注册模块
@passport_blu.route('/register',methods=['POST'])

def register_sucess():
    print("----------------6------------------")
    # 获得从前端获取的参数
    parameter_dict = request.json
    mobile = parameter_dict.get('mobile')
    sms_code = parameter_dict.get('smscode')
    password = parameter_dict.get('password')

    print(mobile + "1")
    print(sms_code + "2")
    print(password + "3")

    # 判断是否缺少参数直接提交
    if not all([mobile,sms_code,password]):
        return jsonify(errno = RET.PARAMERR, errmsg = "缺少参数")

    # 检查 手机验证码是否错误
    try:
        phone_msg = redis_store.get("SMS_" + mobile)
        print(phone_msg)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="手机验证码验证码错误")
    # 如果不存在这个验证码,就证明这个验证码已经过期
    if not phone_msg:
        return jsonify(errno = RET.NODATA, errmsg = "验证码已经过期")
    # 对比用户输入的验证码与 存在redis中的验证码是否一致
    if phone_msg.decode() != str(sms_code):
        return jsonify(errno=RET.DATAERR, errmsg="手机验证码验证码错误")

# TODO 这一段要重点理解  向数据库添加数据的时候必须要初始化数据库模型,密码也需要进行加密操作
    # 开始判断密码是否符合要求
        # 4. 初始化 user 模型，并设置数据并添加到数据库
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    # 对密码进行处理
    user.password = password
    print("------------3------------")
    # 向数据库添加数据
    try:
        db.session.add(user)
        db.session.commit()
        print("--------------4-----------------")
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DATAERR, errmsg = "数据保存失败")

    # 5. 保存用户登录状态
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile
    # session["id_admin"] = user.is_admin

    print("6666666666666666")


    return jsonify(errno=RET.OK, errmsg="注册成功")







"""
      发送短信的逻辑
      1. 获取参数：手机号，图片验证码内容，图片验证码的编号 (随机值)
      2. 校验参数(参数是否符合规则，判断是否有值)
      3. 先从redis中取出真实的验证码内容
      4. 与用户的验证码内容进行对比，如果对比不一致，那么返回验证码输入错误
      5. 如果一致，生成验证码的内容(随机数据)
      6. 发送短信验证码
      7. 告知发送结果
      :return:
      """
# TODO 手机验证码生成  以及发送
@passport_blu.route('/smscode',methods=['POST'])
def send_sms_code():


    # 1. 获取参数：手机号，图片验证码内容，图片验证码的编号 (随机值)
    # params_dict = json.loads(request.data)
    params_dict = request.json

    mobile = params_dict.get("mobile")
    image_code = params_dict.get("image_code")
    image_code_id = params_dict.get("image_code_id")
    print(mobile)
    print(image_code)
    print(image_code_id)

    # 2. 校验参数(参数是否符合规则，判断是否有值)
    # 判断参数是否有值
    if not all([mobile, image_code, image_code_id]):
        # {"errno": "4100", "errmsg": "参数有误"}
        return jsonify(errno=RET.PARAMERR, errmsg="参数有误")
    # 校验手机号是否正确
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

    # 3. 先从redis中取出真实的验证码内容
    try:
        real_image_code = redis_store.get("ImageCode_" + image_code_id)
        # 从redis里面取出来的值为字节型,需要将其转换为字符串
        real_image_code = real_image_code.decode()
        print(real_image_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询失败")

    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg="图片验证码已过期")

    # 4. 与用户的验证码内容进行对比，如果对比不一致，那么返回验证码输入错误
    if real_image_code.upper() != image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg="验证码输入错误")
    print("----------------1---------------")

    # 5. 如果一致，生成短信验证码的内容(随机数据)
    # 随机数字 ，保证数字长度为6位，不够在前面补上0
    sms_code_str = "%06d" % random.randint(0, 999999)
    print("----------------2---------------")
    current_app.logger.debug("短信验证码内容是：%s" % sms_code_str)


    # 6. 发送短信验证码
    # result = CCP().send_template_sms(mobile, [sms_code_str, constants.SMS_CODE_REDIS_EXPIRES / 5], "1")
    # print("发送验证码结果为 %d" % result)
    # if result != 0:
    #     # 代表发送不成功
    #     return jsonify(errno=RET.THIRDERR, errmsg="发送短信失败")
    #



    # 保存验证码内容到redis
    try:
        redis_store.set("SMS_" + mobile, sms_code_str, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据保存失败")

    # 7. 告知发送结果
    return jsonify(errno=RET.OK, errmsg="发送成功")


#  TODO 用户登录生成图片验证码的逻辑
@passport_blu.route('/image_code')
def get_image_code():
    """
    获取图片验证码
    :return:
    """

    # 1. 获取到当前的图片编号id
    code_id = request.args.get('imageCodeId')
    # 2. 生成验证码
    name, text, image = captcha.generate_captcha()
    current_app.logger.error(text)
    try:
        # 保存当前生成的图片验证码内容
        redis_store.setex('ImageCode_' + code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        current_app.logger.error(e)
        return make_response(jsonify(errno=RET.DATAERR, errmsg='保存图片验证码失败'))


    # 返回响应内容
    resp = make_response(image)
    # 设置内容类型
    resp.headers['Content-Type'] = 'image/jpg'
    return resp




